package com.thejaswi.commons;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */



import java.math.BigInteger;

/**
 *
 * @author raj
 */
public class NumberBase {
    private static AlphaNumericDigits andi=new AlphaNumericDigits();
    
   public static String changeBase(String inValue, int fromBase, int targetBase) 
         throws IllegalDigitForCurrentBaseException, InvalidBaseException {
      if ( targetBase > andi.length() ) {
         throw new InvalidBaseException("Target base "+targetBase+" exceeds current max "+andi.length());
      }
      inValue=inValue.replaceAll("[^0-9A-Z]", "");
      return decimalToBase(baseToDecimal(inValue,fromBase), targetBase);
   }

   private static String decimalToBase(String inNum, int newBase) {
   BigInteger dividend=new BigInteger(inNum);
   BigInteger divisor=BigInteger.valueOf(newBase);
   int remainder=0;
   String newNumber="";

   while (dividend.compareTo(divisor)>0) {
      BigInteger[] values = dividend.divideAndRemainder(divisor);
      remainder=values[1].intValue();
      newNumber=andi.getDigit(remainder)+newNumber;
      dividend=values[0];
   }
   remainder=dividend.intValue();
   newNumber=(remainder>0 ? andi.getDigit(remainder)+newNumber : newNumber);
   return newNumber;
   }

   private static String baseToDecimal(String inNumber, int currBase)
         throws IllegalDigitForCurrentBaseException {
      String outNumber="";

      BigInteger unitValue=BigInteger.ZERO;
      BigInteger biBase=BigInteger.valueOf((long)currBase);
      BigInteger multiplier=BigInteger.ZERO;
      int power=0;

      for (int i=inNumber.length()-1;i>=0;i--) {
         multiplier=biBase.pow(power);
         int charDecimal=andi.getDecimalValue(inNumber.charAt(i));
         if ( charDecimal > currBase ) {
            throw new IllegalDigitForCurrentBaseException(
                    "Illegal digit "+inNumber.charAt(i)+" in input for base-"+currBase);
         }
         unitValue=unitValue.add(BigInteger.valueOf((long)charDecimal).multiply(multiplier));
         power++;
      }
      outNumber=unitValue.toString();
      return outNumber;
   }

}
